import { ServerTimeSync } from "./ServerTimeSync";

// TimeManager.ts - Cocos Creator 2.4.15 适配版
const { ccclass } = cc._decorator;

/**
 * 时间模式：控制定时器如何受 timeScale 影响
 */
export enum TimeMode {
  /**
   * 真实时间流逝，不受 timeScale 影响
   * 适用于：服务器倒计时、广告冷却、真实CD
   */
  REALTIME,

  /**
   * 游戏时间，受 timeScale 影响
   * 适用于：战斗技能、UI动画、剧情播放
   */
  GAMETIME,
}

/**
 * 定时器对象封装
 */
class Timer {
  public id: number;
  public duration: number; // 总时长（秒）
  public elapsed: number = 0; // 已流逝时间
  public repeat: boolean; // 是否重复
  public mode: TimeMode; // 时间模式
  public onTick?: (elapsed: number, remaining: number) => void;
  public onComplete?: () => void;
  public owner: cc.Component | null; // 所属组件（用于自动清理）

  constructor(
    id: number,
    duration: number,
    repeat: boolean,
    mode: TimeMode,
    onTick?: (elapsed: number, remaining: number) => void,
    onComplete?: () => void,
    owner?: cc.Component | null
  ) {
    this.id = id;
    this.duration = duration;
    this.repeat = repeat;
    this.mode = mode;
    this.onTick = onTick;
    this.onComplete = onComplete;
    this.owner = owner || null;
  }

  /**
   * 更新定时器
   * @param realDeltaTime 实际时间增量（秒）
   * @param timeScale 当前时间缩放
   * @returns 是否继续存在（false 表示应被移除）
   */
  update(realDeltaTime: number, timeScale: number): boolean {
    let dt = realDeltaTime;

    // 根据时间模式决定是否应用 timeScale
    if (this.mode === TimeMode.GAMETIME) {
      dt *= timeScale;
    }

    this.elapsed += dt;

    // 触发 Tick
    if (this.onTick) {
      try {
        this.onTick(this.elapsed, Math.max(0, this.duration - this.elapsed));
      } catch (e) {
        console.error(`Timer ID=${this.id} onTick error:`, e);
      }
    }

    // 检查是否完成
    if (this.elapsed >= this.duration) {
      if (this.onComplete) {
        try {
          this.onComplete();
        } catch (e) {
          console.error(`Timer ID=${this.id} onComplete error:`, e);
        }
      }

      if (this.repeat) {
        this.elapsed = 0;
        return true; // 继续存在
      } else {
        return false; // 标记为移除
      }
    }

    return true; // 继续存在
  }

  reset() {
    this.elapsed = 0;
  }
}

/**
 * 全局时间管理器（单例）
 * 统一管理所有延时、计时、时间缩放、暂停等功能
 * 适用于 Cocos Creator 2.4.15
 */
@ccclass
export class TimeManager extends cc.Component {
  private static _instance: TimeManager | null = null;

  /**
   * 获取单例实例
   * 如果未初始化，会自动创建一个节点并挂载
   */
  public static get instance(): TimeManager {
    if (!TimeManager._instance) {
      // 查找已有节点
      let node = cc.director.getScene().getChildByName("TimeManager");
      if (!node) {
        node = new cc.Node("TimeManager");
        node.setPosition(0, 0);
        cc.director.getScene().addChild(node);
      }

      // 获取或添加组件
      const tm = node.getComponent(TimeManager);
      if (tm) {
        TimeManager._instance = tm;
      } else {
        TimeManager._instance = node.addComponent(TimeManager);
      }
    }
    return TimeManager._instance;
  }

  // 当前时间缩放（默认1.0）
  private _timeScale: number = 1.0;
  public get timeScale(): number {
    return this._timeScale;
  }

  // 是否暂停
  private _isPaused: boolean = false;
  public get isPaused(): boolean {
    return this._isPaused;
  }

  // 定时器集合
  private _timers: Map<number, Timer> = new Map();
  private _timerIdCounter: number = 0;

  // 上一帧时间戳（用于计算 deltaTime）
  private _lastRealTime: number = 0;

  // 是否已启动
  private _started: boolean = false;

  // ======================== 生命周期 ========================

  onLoad() {
    // 防止重复实例化
    if (TimeManager._instance && TimeManager._instance !== this) {
      console.warn("TimeManager already exists, destroying duplicate.");
      this.destroy();
      return;
    }
    TimeManager._instance = this;
  }

  onEnable() {
    // 每次场景激活时重新开始调度
    if (!this._started) {
      this.start();
    }
  }

  start() {
    if (this._started) return;
    this._started = true;
    this._lastRealTime = performance.now() / 1000;
    this.schedule(this.update, 0); // 每帧更新
  }

  update() {
    const now = performance.now() / 1000;
    if (this._lastRealTime === 0) {
      this._lastRealTime = now;
      return;
    }

    const realDeltaTime = now - this._lastRealTime;
    this._lastRealTime = now;

    if (!this._isPaused) {
      this.updateTimers(realDeltaTime);
    }
  }

  onDestroy() {
    // 清理所有定时器
    this.unScheduleAll();
    TimeManager._instance = null;
  }

  // ======================== 定时器更新 ========================

  /**
   * 内部更新所有定时器
   */
  private updateTimers(realDeltaTime: number) {
    // 避免在遍历时删除导致的问题
    const toRemove: number[] = [];

    for (const [id, timer] of this._timers) {
      try {
        const keep = timer.update(realDeltaTime, this._timeScale);
        if (!keep) {
          toRemove.push(id);
        }
      } catch (e) {
        console.error(`Timer ID=${id} update error:`, e);
        toRemove.push(id);
      }
    }

    // 批量移除
    for (const id of toRemove) {
      this._timers.delete(id);
    }
  }

  // ======================== 公共 API：定时器 ========================

  /**
   * 延迟执行一次
   * @param delay 延迟时间（秒）
   * @param owner 所属组件（自动绑定生命周期）
   * @param callback 回调函数
   * @param mode 时间模式（默认 GAMETIME）
   * @returns 定时器ID，可用于手动取消
   */
  delayCall(
    delay: number,
    owner: cc.Component,
    callback: () => void,
    mode: TimeMode = TimeMode.GAMETIME
  ): number {
    if (delay <= 0) {
      callback();
      return -1;
    }

    const timer = new Timer(
      ++this._timerIdCounter,
      delay,
      false,
      mode,
      undefined,
      callback,
      owner
    );

    this.bindOwner(timer);
    this._timers.set(timer.id, timer);
    return timer.id;
  }

  /**
   * 重复执行
   * @param interval 间隔时间（秒）
   * @param owner 所属组件
   * @param callback 回调
   * @param mode 时间模式
   * @returns 定时器ID
   */
  repeatCall(
    interval: number,
    owner: cc.Component,
    callback: () => void,
    mode: TimeMode = TimeMode.GAMETIME
  ): number {
    if (interval <= 0) {
      console.warn("repeatCall: interval must be > 0");
      return -1;
    }

    const timer = new Timer(
      ++this._timerIdCounter,
      interval,
      true,
      mode,
      undefined,
      undefined,
      owner
    );

    timer.onTick = () => {
      try {
        callback();
      } catch (e) {
        console.error("repeatCall callback error:", e);
      }
    };

    this.bindOwner(timer);
    this._timers.set(timer.id, timer);
    return timer.id;
  }

  /**
   * 倒计时（带 tick 回调）
   * @param duration 总时长（秒）
   * @param owner 所属组件
   * @param onTick 每帧回调（elapsed, remaining）
   * @param onComplete 结束回调
   * @param mode 时间模式
   * @returns 定时器ID
   */
  countdown(
    duration: number,
    owner: cc.Component,
    onTick?: (elapsed: number, remaining: number) => void,
    onComplete?: () => void,
    mode: TimeMode = TimeMode.GAMETIME
  ): number {
    const timer = new Timer(
      ++this._timerIdCounter,
      duration,
      false,
      mode,
      onTick,
      onComplete,
      owner
    );

    this.bindOwner(timer);
    this._timers.set(timer.id, timer);
    return timer.id;
  }

  // ======================== 时间控制 API ========================

  /**
   * 设置时间缩放（用于战斗加速、慢动作等）
   * @param scale 缩放值（0.1 ~ 4.0 推荐）
   */
  setTimeScale(scale: number) {
    this._timeScale = Math.max(0.01, scale); // 防止为0卡死
  }

  /**
   * 暂停所有 GAMETIME 定时器
   */
  pause() {
    this._isPaused = true;
  }

  /**
   * 恢复时间流动
   */
  resume() {
    this._isPaused = false;
  }

  // ======================== 定时器清理 API ========================

  /**
   * 取消指定ID的定时器
   */
  unSchedule(id: number) {
    this._timers.delete(id);
  }

  /**
   * 取消某个组件（owner）的所有定时器
   */
  unScheduleByOwner(owner: cc.Component) {
    for (const [id, timer] of this._timers) {
      if (timer.owner === owner) {
        this._timers.delete(id);
      }
    }
  }

  /**
   * 清除所有定时器（谨慎使用）
   */
  unScheduleAll() {
    this._timers.clear();
  }

  /**
   * 获取某个组件拥有的定时器数量（调试用）
   */
  getCountByOwner(owner: cc.Component): number {
    let count = 0;
    for (const timer of this._timers.values()) {
      if (timer.owner === owner) {
        count++;
      }
    }
    return count;
  }

  // ======================== 内部工具：绑定组件生命周期 ========================

  /**
   * 绑定定时器到组件，自动在组件销毁时清理
   */
  private bindOwner(timer: Timer) {
    const owner = timer.owner;
    if (!owner || !owner.isValid) return;

    // 避免重复绑定
    if ((owner as any).__hasTimerCleanup) return;
    (owner as any).__hasTimerCleanup = true;

    owner.node.once("destroy", () => {
      this.unScheduleByOwner(owner);
      (owner as any).__hasTimerCleanup = false;
    });
  }

  // ======================== 调试工具（可选） ========================

  /**
   * 打印当前所有活跃定时器（调试用）
   */
  debugListTimers() {
    console.group("⏰ Active Timers:");
    for (const [id, timer] of this._timers) {
      const ownerName = timer.owner ? timer.owner.name : "null";
      const mode = timer.mode === TimeMode.GAMETIME ? "GAMETIME" : "REALTIME";
      console.log(
        `ID=${id} | Owner=${ownerName} | Mode=${mode} | Elapsed=${timer.elapsed.toFixed(
          2
        )}/${timer.duration.toFixed(2)}`
      );
    }
    console.groupEnd();
  }

  /**
   * 获取当前时间戳（毫秒）
   * @returns 当前时间的毫秒级时间戳
   */
  static getNowMillisecond(): number {
    return Date.now();
  }

  /**
   *获取服务器时间
   */
  public getServerTime(): number {
    return ServerTimeSync.instance.getServerTime();
  }
}
